﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using TanmiaGrp.GeneralLedger.Core;
using TanmiaGrp.GeneralLedger.Domain;
using TanmiaGrp.GeneralLedger.WinApp.Commands;
using TanmiaGrp.Basis;
using System.ComponentModel;
using System.Windows.Data;

namespace TanmiaGrp.GeneralLedger.WinApp.Scenarios
{
    public class AccountBrowserViewModel : BaseBrowserViewModel<Account, AccountDomain>
    {
        private Account root;
        private Account selectedAccount;
        private ICollectionView statementOfAccount;

        public Account SelectedAccount
        {
            get { return selectedAccount; }
            set
            {
                if (selectedAccount != value)
                {
                    selectedAccount = value;
                    RaisePropertyChanged(() => SelectedAccount);

                    OnCurrentEntityChanged(this, EventArgs.Empty);
                }
            }
        }

        public ICollectionView StatementOfAccount
        {
            get { return statementOfAccount; }
            set
            {
                if (statementOfAccount != value)
                {
                    statementOfAccount = value;
                    RaisePropertyChanged(() => StatementOfAccount);
                }
            }
        }

        public AccountBrowserViewModel()
        {
            BusinessDomain = AccountDomain.Obj;

            EntitySavedOrDeletedEvent = Events.AccountEntitySavedOrDeleted;
            EntityNavigationEvent = Events.AccountEntityNavigation;
            BrowserInitializedEvent = Events.AccountBrowserInitialized;
            PageNavigationEvent = Events.AccountPageNavigation;

            Initialize();

            EditorView = ViewNames.AccountEditor;
            BrowserView = ViewNames.AccountBrowser;
        }

        #region Main Business Logic

        protected override bool CanEdit(Account arg)
        {
            if (arg == null && SelectedAccount != null)
                arg = SelectedAccount;

            return base.CanEdit(arg);
        }

        protected override void OnEdit(Account arg)
        {
            if (arg == null && SelectedAccount != null)
                arg = SelectedAccount;

            base.OnEdit(arg);
        }

        protected override void OnAdd(Account arg)
        {
            try
            {
                if (arg == null && SelectedAccount != null)
                    arg = SelectedAccount;

                Account newChildAccount = BusinessDomain.CreateNewChild(SelectedAccount);
                newChildAccount.CaptureState();

                Messages.NewAccount.Send(newChildAccount);

                UpdateCurrentViewEvent
                    .Fire(EditorView);

                RaiseBrowserStateChangedEvent();
            }
            catch (BaseAppException appEx)
            {
                UserMessageSvc.ShowErrorMessage(appEx);
            }
        }

        #endregion Main Business Logic

        #region Helper Methods

        protected override System.ComponentModel.ICollectionView MapEntities(List<Account> entities)
        {
            root = Account.ChartOfAccountHeader.Clone() as Account;
            root.AccountChildren = entities;
            root.IsExpanded = true;
            root.IsSelected = true;
            return base.MapEntities(new List<Account> { root });
        }

        private static IEnumerable<Account> GetAllChildAccounts(Account root)
        {
            foreach (Account child in root.AccountChildren)
            {
                yield return child;

                if (child.AccountChildren.Count > 0)
                    foreach (Account grandChild in GetAllChildAccounts(child))
                        yield return grandChild;
            }
        }

        protected override void RaisePropertyChanged(string propertyName)
        {
            base.RaisePropertyChanged(propertyName);

            if (propertyName == "SelectedAccount") OnSelectedAccountChanged();
        }

        private void OnSelectedAccountChanged()
        {
            if (SelectedAccount != null && SelectedAccount.IsTransactional)
            {
                StatementOfAccount = CollectionViewSource.GetDefaultView(VoucherDomain.Obj.GetStatementOfAccount(SelectedAccount));
            }
        }

        private void SelectAccountNode(Account account)
        {
            Account item = GetAllChildAccounts(root).FirstOrDefault(x => x.AccountNumber == account.AccountNumber) ?? root;

            item.IsSelected = true;
            item = item.Parent;
            while (item != null)
            {
                item.IsExpanded = true;
                item = item.Parent;
            }
        }

        #endregion Helper Methods


        protected override void SearchSpecificationChangedHandler(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "InteractiveSearch")
            {
                Account item = GetAllChildAccounts(root)
                    .FirstOrDefault(x => x.AccountNumber.Contains(SearchSpecification.InteractiveSearch)
                        || x.AccountName.Contains(SearchSpecification.InteractiveSearch)) ?? root;

                SelectAccountNode(item);
            }
            else if (e.PropertyName == "ShowIsDisabled")
            {
                if (!ProgressObj.IsProgress)
                    base.SearchSpecificationChangedHandler(sender, e);
            }
        }

        protected override void OnEntitiesTaskChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnEntitiesTaskChanged(sender, e);
            if (e.PropertyName == "IsSuccessfullyCompleted")
            {
                if (SelectedAccount != null)
                    SelectAccountNode(SelectedAccount);
            }
        }
    }
}